package huaweiclouddns

import (
	// "flag"
	"strings"

	log "ddns/log"
	"ddns/parameter"

	"github.com/forease/gotld"
	"github.com/huaweicloud/huaweicloud-sdk-go-v3/core/auth/basic"
	dns "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/dns/v2"
	"github.com/huaweicloud/huaweicloud-sdk-go-v3/services/dns/v2/model"
	region "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/dns/v2/region"
)

func AddSet(C dns.DnsClient, ZoneId, Name string, ips []string) (parameter.Requestinfo, error) {
	P := parameter.Requestinfo{}
	request := &model.CreateRecordSetRequest{}
	request.ZoneId = ZoneId
	var listRecordsbody = ips
	request.Body = &model.CreateRecordSetReq{
		Records: listRecordsbody,
		Type:    "A",
		Name:    Name,
	}
	response, err := C.CreateRecordSet(request)
	if err != nil {
		return P, err
	}
	P.ZoneId = *response.ZoneId
	P.ID = *response.Id
	P.Name = *response.Name
	P.Status = *response.Status
	return P, nil
}

func UpdateSet(C dns.DnsClient, ZoneId, RecordsetId, Name string, ips []string) (parameter.Requestinfo, error) {
	P := parameter.Requestinfo{}
	request := &model.UpdateRecordSetRequest{}
	request.ZoneId = ZoneId
	request.RecordsetId = RecordsetId
	var listRecordsbody = ips
	request.Body = &model.UpdateRecordSetReq{
		Records: &listRecordsbody,
		Type:    "A",
		Name:    Name,
	}
	response, err := C.UpdateRecordSet(request)
	if err != nil {
		return P, err
	}
	P.ZoneId = *response.ZoneId
	P.ID = *response.Id
	P.Name = *response.Name
	P.Status = *response.Status
	return P, nil
}

func NewClient(dcfg parameter.DomainCfg) *dns.DnsClient {
	ak := dcfg.Accesskey
	sk := dcfg.Secretkey
	re := dcfg.RegionName
	auth := basic.NewCredentialsBuilder().
		WithAk(ak).
		WithSk(sk).
		Build()
	client := dns.NewDnsClient(
		dns.DnsClientBuilder().
			WithRegion(region.ValueOf(re)).
			WithCredential(auth).
			Build())
	return client
}

func DoneUp(dcfg parameter.DDNSCfg, ips []string) error {
	dnsclient := NewClient(dcfg.DomainCfg)
	log.Debugln("Get the huawei DNS Client success!")
	for _, domain := range dcfg.DomainCfg.Domains {
		log.Debugf("Update this domain: %v\n", domain)
		DoneUpone(*dnsclient, ips, string(domain))
	}
	return nil
}

func DoneUpone(C dns.DnsClient, ips []string, domainName string) {

	// 通过华为云的ka、sk、re生成一个client
	// C := NewClient(dcfg.DomainCfg)

	// 通过域名添加查询一个A类型的请求
	request := &model.ListRecordSetsRequest{}
	statusRequest := "ACTIVE"
	request.Status = &statusRequest
	typeRequest := "A"
	request.Type = &typeRequest
	request.Name = &domainName
	//执行查询请求
	log.Debugf("Get this domain info of A Type: %v\n", domainName)
	response, err := C.ListRecordSets(request)
	if err != nil {
		log.Errorf("Get this domain info of A Type error: %v\n", err)
	}

	// 查询结果中，判断是否是自己的域名，是新增还是更新
	//   查询A类型的个数是0，再获取请求域名对应的顶级域名，查询顶级域名的SOA记录是否存在，
	// 	    不存在，则不是自己的域名，
	// 	    存在，再请求域名跟解析出来的顶级域名是否是同一个，是同一个，则不添加A记录，不是同一个，则新增加一条记录
	//   查询A类型的个数不是是0，则将该域名下的全部A记录的id取出来，然后挨个修改其记录值
	if *response.Metadata.TotalCount == 0 {
		log.Debugf("This domain have's no A Type, check the top domain. this domain is: %v\n", domainName)
		// 获取顶级域名
		domainname := strings.TrimSuffix(domainName, ".")
		_, domain, err := gotld.GetTld(domainname)
		if err != nil {
			log.Errorf("Get domain's top domain error: %v\n", err)
		} else {
			// 准备请求SOA记录
			log.Debugf("Get the top domain info. this Top domain is: %v\n", domain)
			request.Name = &domain
			typeRequest = "SOA"
			response, err = C.ListRecordSets(request)
			if err != nil {
				log.Errorf("Get the top domain info err : %v\n", err)
			}
			// SOA记录数是否为0
			if *response.Metadata.TotalCount == 0 {
				// 0表示不是自己的
				log.Debugf("This domain is not yours: %v\n", domain)
			} else {
				// 不是0，则查看请求域名跟顶级域名是不是同一个
				if domain != domainname {
					// 不是同一个，则添加记录
					log.Debugf("Add this domain: %v\n", domain)
					for i, n := range *response.Recordsets {
						if i == 0 {
							// 添加请求，并执行新增操纵
							Zoneid := n.ZoneId
							resquest, err := AddSet(C, *Zoneid, domainName, ips)
							if err != nil {
								log.Errorf("Add this domain Recordsets err : %v\n", err)
							} else {
								log.Debugf("Add this domain Recordsets sucess: %v, this recoresets id is : %v, status is: %v\n", domain, resquest.ID, resquest.Status)
							}
						}
					}
				} else {
					// 查询的域名跟顶级域名是同一个，跳过该操作
					log.Debugf("This domain is Top domain, and jump this domain: %v\n", domain)
				}
			}
		}
	} else {
		// 该域名查询的A记录不为零，则挨个取出对应的id
		for _, v := range *response.Recordsets {
			log.Debugf("Update the Recordsets info: %v\n", *v.Name)
			// fmt.Println(i, *v.Id, *v.ZoneId, *v.Name)
			// 通过id进行修改对应值
			resquest, err := UpdateSet(C, *v.ZoneId, *v.Id, *v.Name, ips)
			if err != nil {
				log.Errorf("Update this domain Recordsets err : %v\n", err)
			} else {
				log.Debugf("Update the Recordsets status: %v, ID: %v\n", resquest.Status, resquest.ID)
			}
		}
	}
}
